home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
cmidilib.zip
/
CRACK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-23
|
4KB
|
106 lines
/*
* crack - put the command line to the vice.
*
* This routine takes four arguments, the variables argc and argv from
* the program's main procedure, a list of flags to recognize, and an
* indication whether to ignore unknown flags or not.
*
* The action of crack is to read a command line laid out in the format:
*
* % command [flags]... [files]...
*
* where the flags are of the form -foption, that is, a minus, a character
* and an optional argument, butted up to the character. No space may
* appear between any flag and its option. The first command line
* argument not preceeded by '-' is taken as the end of the flags and the
* beginning of file names.
*
* The flags argument to crack looks like this: "a|b|cd" for flags a b c
* and d. In this example, a and b take (optional!) options, as specified
* by the trailing colon, c and d do not. When crack scans a flag, it
* returns the flag character after setting the external character pointer
* arg_option to the option part. It also sets arg_index to the index of
* the argv variable scanned. Crack returns NULL when it has scanned the
* last flag. The value of arg_index then points at the first
* argument after the last flag, which should be the first filename, if
* any. If there are no arguments, or no more arguments after reading
* the flags, arg_index == argc;
*
* Flags may be concatenated, for instance, using the flags argument
* given above: -cd will treat c and d as
* flags. -cdaoption also works. However, tacking what you think is
* a flag after another flag that takes an option will cause the flag to
* be lost. I.e., -ac will treat c as an option, not a flag.
*
* When the ignore flag is zero, flags scanned that are not in the flags
* variable generate an error message and crack returns EOF. If ignore is
* nonzero, unknown flags are suppressed, that is, no flag is returned.
* The purpose of ignoring flags is so that more than one part of a
* program can scan the command line without having to know about the
* flags of all the other parts. For instance, where a program calculates
* a sampling rate by one flag and a value in seconds in another, it must
* search for the sampling rate first, then the time value. Two calls to
* crack() would be required, one to scan just for the flag setting sampling
* rate, another to ignore the rate flag, but to set the time value based
* on the sampling rate.
* NOTE: WHEN MAKING MORE THAN ONE CALL TO crack() IN A PROGRAM, IT
* IS NECESSARY TO RESET arg_index TO 0 FIRST.
*
* When ignoring unknown flags, if an unknown flag has an option
* associated with it, the option is also ignored. Care should be excercised
* here because it may be possible that the associated "option" is really
* more concatenated flags. These, if any, are lost. The rule is that,
* when ignoring unknown flags, the first instance of an unknown flag
* causes that flag and the rest of that argument to be discarded. For
* instance, if flags is set to "a:b:cd", and a command line:
* "-zcdaoption" is supplied, c d and a would be ignored because they come
* after z in the same argument. The point is there is no way to disambiguate
* flags from unknown options when ignoring flags, so concatenating options,
* while nice, is problematical.
*/
#include <stdio.h>
int arg_index = 0;
char *arg_option;
char *pvcon = NULL;
char crack(argc, argv, flags, ign)
int argc; char **argv; char *flags; int ign;
{
char *pv, *flgp, *strchr();
while ((arg_index) < argc)
{
if (pvcon != NULL)
pv = pvcon;
else
{
if (++arg_index >= argc) return(NULL);
pv = argv[arg_index];
if (*pv != '-')
return(NULL);
}
pv++; /* skip '-' or prev. flag */
if (*pv != NULL)
{
if ((flgp=strchr(flags,*pv)) != NULL)
{
pvcon = pv;
if (*(flgp+1) == '|') { arg_option = pv+1; pvcon = NULL; }
return(*pv);
}
else
if (!ign)
{
fprintf(stderr, "%s: no such flag: %s\n", argv[0], pv);
return(EOF);
}
else
pvcon = NULL;
}
pvcon = NULL;
}
return(NULL);
}